package com.ccl.iot;

import com.ccl.iot.IOTObject.IOTScannableObject;
import com.ccl.iot.IOTObject.IOTScannableObject.IOTScanListener;

import java.util.List;

public class IOTListScanner<TYPE> {
    public static final int KSCAN_TIME_OUT = 3000;

    public interface ScanImpl<TYPE> {
        public void scanStart();

        public List<TYPE> scanDevices();

        public void scanDone();
    }

    private Object iScanLock = new Object();

    private IOTScannableObject<TYPE> iOwner = null;
    private volatile boolean iScanning = false;
    private int iScanCount = 0;

    public IOTListScanner(IOTScannableObject<TYPE> aOwner) {
        iOwner = aOwner;
    }

    public boolean isScanning() {
        return iScanning;
    }

    public int getScanCount() {
        return iScanCount;
    }

    public boolean startScan(ScanImpl<TYPE> aScanImpl, IOTScanListener<TYPE> aListener) {
        if (aScanImpl != null) {
            synchronized (iScanLock) {
                if (iScanning == false) {
                    iScanning = true;

                    iScanCount++;
                } else {
                    return false;
                }

                if (aListener != null) {
                    aListener.onScanStart(iOwner);
                }

                aScanImpl.scanStart();

                List<TYPE> types = aScanImpl.scanDevices();
                if (types != null && types.size() > 0) {
                    for (TYPE type : types) {
                        aListener.onScanResult(iOwner, type);
                    }
                }
            }

            aScanImpl.scanDone();

            iScanning = false;


            if (aListener != null) {
                aListener.onScanStop(iOwner);
            }

            synchronized (iScanLock) {
                iScanLock.notifyAll();
            }

            return true;
        }

        return false;
    }

    public boolean stopScan() {
        synchronized (iScanLock) {
            if (iScanning) {
                iScanning = false;
            } else {
                return false;
            }
        }

        synchronized (iScanLock) {
            try {
                iScanLock.wait(KSCAN_TIME_OUT);
            } catch (InterruptedException e) {
            }
        }

        return true;
    }

    public void reset() {
        stopScan();

        iScanCount = 0;
    }
}
